package com.hy.${packageCode}.shared.utils;

import com.hy.${packageCode}.shared.model.ProcessResultDTO;
import com.hy.${packageCode}.shared.model.ProcessResultDTO;
import com.hy.${packageCode}.shared.model.ProcessResultDTO;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

@Slf4j
public class ProcessUtil {

    private ProcessUtil() {
    }

    public static ProcessResultDTO executeCmd(String[] command) throws IOException {
            log.debug("execute cmd:{}", String.join(" ", command));
            Process process = Runtime.getRuntime().exec(command);

            try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
                 ExecutorService errorExecutor = Executors.newVirtualThreadPerTaskExecutor()) {
                // 读取标准输出
                Future<String> stdoutFuture = executor.submit(() -> {
                    StringBuilder outMessage = new StringBuilder();
                    try (BufferedReader brOut = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                        String line;
                        while ((line = brOut.readLine()) != null) {
                            log.debug("out:{}", line);
                            outMessage.append(line).append("\n");
                        }
                    }
                    return outMessage.toString();
                });
                // 读取错误输出
                Future<String> stderrFuture = errorExecutor.submit(() -> {
                    StringBuilder errMessage = new StringBuilder();
                    try (BufferedReader brErr = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
                        String line;
                        while ((line = brErr.readLine()) != null) {
                            log.error("err:{}", line);
                            errMessage.append(line).append("\n");
                        }
                    }
                    return errMessage.toString();
                });
                try {
                    int exitCode = process.waitFor();
                    // 获取输出结果
                    String outMsg = stdoutFuture.get();
                    String errMsg = stderrFuture.get();
                    return ProcessResultDTO.builder()
                            .code(exitCode)
                            .errorMsg(outMsg)
                            .outMsg(errMsg)
                            .build();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new BusinessException(e.getMessage());
                }catch (ExecutionException e){
                    throw new BusinessException(e.getMessage());
                }
            }
        }
}
